package com.gugu.procedure.util;


import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class ImageUtil {

    /**
     * 压缩图片
     *
     * @param fromPic
     * @throws IOException
     */
    public static void compressImage(File fromPic) throws IOException {
        byte[] bytes = FileUtils.readFileToByteArray(fromPic);
        bytes = compressPicForScale(bytes, 1024 * 5, "x");// 图片小于300kb
        FileUtils.writeByteArrayToFile(new File(fromPic.getAbsoluteFile() + fromPic.getName()), bytes);

    }

    public static byte[] compressImageForBytes(byte[] bytes) {
        bytes = compressPicForScale(bytes, 1024 * 5, "x");// 图片小于300kb
        return bytes;
    }

    /**
     * 根据指定大小压缩图片
     *
     * @param imageBytes  源图片字节数组
     * @param desFileSize 指定图片大小，单位kb
     * @param imageId     影像编号
     * @return 压缩质量后的图片字节数组
     */
    public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize, String imageId) {
        if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
            return imageBytes;
        }
        long srcSize = imageBytes.length;
        double accuracy = getAccuracy(srcSize / 1024);
        try {
            int count = 1; //设置最多循环次数 避免下面出现死循环
            while (imageBytes.length > desFileSize * 1024 && accuracy < 1) {
                System.out.println("第" + count + "次压缩前大小" + imageBytes.length / 1024);
                ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
                Thumbnails.of(inputStream)
                        .scale(accuracy)
                        .outputQuality(accuracy)
                        .toOutputStream(outputStream);
                imageBytes = outputStream.toByteArray();
                System.out.println("第" + count + "次压缩后大小" + imageBytes.length / 1024);
                count++;
                if (count > 10) {
                    break;
                }
            }
            System.out.println("压缩比例：" + accuracy);
            System.out.println("图片压缩】原图大小(kb)" + srcSize / 1024);
            System.out.println("图片压缩】压缩后大小(kb)" + imageBytes.length / 1024);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return imageBytes;

        }
        return imageBytes;
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy = 1.0;
        if (size <= 1024 * 5) {
            return accuracy;
        } else if (100 < size && size <= 200) {
            accuracy = 0.98;
        } else if (200 < size && size <= 400) {
            accuracy = 0.95;
        } else if (400 < size && size <= 700) {
            accuracy = 0.90;
        } else if (700 < size && size <= 1000) {
            accuracy = 0.85;
        } else if (1000 < size) {
            accuracy = 0.80;
        } else {
            accuracy = 0.80;
        }
        return accuracy;
    }

    /**
     * 根据图片url获取图片
     *
     * @param url
     * @return
     */
    private static BufferedImage getBufferedImageFromUrl(String url) throws IOException {
        if (url.startsWith("https://") || url.startsWith("http://")) {
            return ImageIO.read(new URL(url));
        } else {
            return ImageIO.read(new File(url));
        }
    }

    /**
     * 图片合成
     *
     * @param backgroundPath 底图
     * @param smallPath      小图
     * @param type           生成图片类型jpg,png...
     * @param resultPaht     生成图片保存路径
     */
    public static void image(String backgroundPath, String smallPath, String type, String resultPaht) {
        try {

            BufferedImage small = getBufferedImageFromUrl(smallPath);
            BufferedImage image = getBufferedImageFromUrl(backgroundPath);
            //生成画笔
            Graphics g = image.getGraphics();
            g.drawImage(small, image.getWidth() - small.getWidth(), image.getHeight() - small.getHeight(),
                    image.getWidth(), image.getHeight(), null);
            ImageIO.write(image, type, new File(resultPaht));
        } catch (IOException e) {
            throw new RuntimeException("合成图片失败", e);
        }
    }

    /**
     * @throws
     * @Title: modifyImagetogeter
     * @Description: 将几张图片合成一张图片
     * @param: @param b1
     * @param: @param b2
     * @param: @param b3
     * @param: @return
     * @return: BufferedImage
     * @author:石德斌
     * @date:2020年4月21日 下午3:26:41
     */
    //创建一个304*304的图片
    public static BufferedImage modifyImagetogeter(BufferedImage[] image) {
        BufferedImage tag = new BufferedImage(304, 304, BufferedImage.TYPE_INT_RGB);
        try {
            Graphics2D graphics = tag.createGraphics();
            //设置颜色为218，223，224
            graphics.setColor(new Color(218, 223, 224));
            //填充颜色
            graphics.fillRect(0, 0, 304, 304);
            int count = image.length;
            //根据不同的合成图片数量设置图片放置位置
            if (count == 1) {
                int startX = 108;
                int startY = 108;
                BufferedImage b = image[0];
                graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
            } else if (count == 2) {
                int startX = 60;
                int startY = 108;
                BufferedImage b1 = image[0];
                graphics.drawImage(b1, startX, startY, b1.getWidth(), b1.getHeight(), null);
                BufferedImage b2 = image[1];
                startX = startX + b1.getWidth() + 8;
                graphics.drawImage(b2, startX, startY, b2.getWidth(), b2.getHeight(), null);
            } else if (count == 3) {
                int startX = 108;
                int startY = 60;
                BufferedImage b1 = image[0];
                graphics.drawImage(b1, startX, startY, b1.getWidth(), b1.getHeight(), null);
                BufferedImage b2 = image[1];
                startX = 60;
                startY = 60 + b1.getHeight() + 8;
                graphics.drawImage(b2, startX, startY, b2.getWidth(), b2.getHeight(), null);
                BufferedImage b3 = image[2];
                startX = startX + b2.getWidth() + 8;
                graphics.drawImage(b3, startX, startY, b3.getWidth(), b3.getHeight(), null);
            } else if (count == 4) {
                int startX = 60;
                int startY = 60;
                BufferedImage b1 = image[0];
                graphics.drawImage(b1, startX, startY, b1.getWidth(), b1.getHeight(), null);
                BufferedImage b2 = image[1];
                startX = 60 + b1.getWidth() + 8;
                graphics.drawImage(b2, startX, startY, b2.getWidth(), b2.getHeight(), null);
                BufferedImage b3 = image[2];
                startX = 60;
                startY = 60 + b2.getHeight() + 8;
                graphics.drawImage(b3, startX, startY, b3.getWidth(), b3.getHeight(), null);
                BufferedImage b4 = image[3];
                startX = 60 + b3.getWidth() + 8;
                graphics.drawImage(b4, startX, startY, b4.getWidth(), b4.getHeight(), null);
            } else if (count == 5) {
                int startX = 60;
                int startY = 60;
                BufferedImage b1 = image[0];
                graphics.drawImage(b1, startX, startY, b1.getWidth(), b1.getHeight(), null);
                BufferedImage b2 = image[1];
                startX = startX + b1.getWidth() + 8;
                graphics.drawImage(b2, startX, startY, b2.getWidth(), b2.getHeight(), null);
                startX = 12;
                startY = 12 + startY + b2.getHeight();
                for (int i = 2; i < count; i++) {
                    BufferedImage b = image[i];
                    graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
                    startX = startX + b.getWidth() + 8;
                }
            } else if (count == 6) {
                int startX = 12;
                int startY = 60;
                for (int i = 0; i < count; i++) {
                    BufferedImage b = image[i];
                    graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
                    startX = startX + b.getWidth() + 8;
                    if ((i + 1) % 3 == 0) {
                        startY = startY + b.getHeight() + 8;
                        startX = 12;
                    }
                }
            } else if (count == 7) {
                int startX = 108;
                int startY = 12;
                BufferedImage b = image[0];
                graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
                startX = 12;
                startY = startY + 8 + b.getHeight();
                for (int i = 1; i < count; i++) {
                    b = image[i];
                    graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
                    startX = startX + b.getWidth() + 8;
                    if (i % 3 == 0) {
                        startY = startY + b.getHeight() + 8;
                        startX = 12;
                    }
                }
            } else if (count == 8) {
                int startX = 60;
                int startY = 12;
                BufferedImage b1 = image[0];
                graphics.drawImage(b1, startX, startY, b1.getWidth(), b1.getHeight(), null);
                BufferedImage b2 = image[1];
                startX = startX + b1.getWidth() + 8;
                graphics.drawImage(b2, startX, startY, b2.getWidth(), b2.getHeight(), null);
                startX = 12;
                startY = 12 + b2.getHeight() + 8;
                for (int i = 2; i < count; i++) {
                    BufferedImage b = image[i];
                    graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
                    startX = startX + b.getWidth() + 8;
                    if (i == 4) {
                        startY = startY + b.getHeight() + 8;
                        startX = 12;
                    }
                }
            } else if (count == 9) {
                int startX = 12;
                int startY = 12;
                for (int i = 0; i < count; i++) {
                    BufferedImage b = image[i];
                    graphics.drawImage(b, startX, startY, b.getWidth(), b.getHeight(), null);
                    startX = startX + b.getWidth() + 8;
                    if ((i + 1) % 3 == 0) {
                        startY = startY + b.getHeight() + 8;
                        startX = 12;
                    }
                }
            }
            graphics.dispose();
        } catch (Exception e) {
            //logger.error("推送同比压缩图片出错{}",e);
            System.out.println(e);
        }

        return tag;
    }

    public static BufferedImage loadImageLocal(String url) {
        try {
            if (url.startsWith("https:") || url.startsWith("http:")) {
                return ImageIO.read(new URL(url));
            } else {
                return ImageIO.read(new File(url));
            }
        } catch (IOException e) {
            //logger.error("推送同比压缩图片出错{}",e);
            System.out.println(e);
        }
        return null;
    }


    public static ImageInputStream writeImageLocal(BufferedImage img) {

        try {
            ImageInputStream is = ImageIO.createImageInputStream(img);
            System.out.println(is);
        } catch (IOException e) {
            //logger.error("推送同比压缩图片出错{}",e);
            System.out.println(e);
        }
        return null;
    }

    public static byte[] imageToBytes(BufferedImage bImage, String format) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ImageIO.write(bImage, format, out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    public static void writeImageLocal(String newImage, BufferedImage img) {
        if (newImage != null && img != null) {
            try {
                File outputfile = new File(newImage);
                ImageIO.write(img, "jpg", outputfile);


            } catch (IOException e) {
                //logger.error("推送同比压缩图片出错{}",e);
                System.out.println(e);
            }
        }
    }

    /**
     * @throws
     * @Title: handleLarge
     * @Description: 同比例压缩图片，使图片形成相同大小
     * @param: @param image
     * @param: @return
     * @return: BufferedImage[]
     * @author:石德斌
     * @date:2020年4月23日 上午10:36:11
     */
    public static BufferedImage[] handleLarge(Integer width, Integer height, BufferedImage[] image) {
        BufferedImage[] b = new BufferedImage[image.length];
        for (int i = 0; i < image.length; i++) {
            BufferedImage sourceImage = image[i];
            try {
                b[i] = zoom2(width, height, sourceImage);
            } catch (Exception e) {
                System.out.println("推送同比压缩图片出错{}");
            }
        }
        return b;
    }


    public static BufferedImage zoom2(int width, int height, BufferedImage sourceImage) {

        if (sourceImage == null) {
            return sourceImage;
        }
        // 计算x轴y轴缩放比例--如需等比例缩放，在调用之前确保參数width和height是等比例变化的
        double ratiox = (new Integer(width)).doubleValue() / sourceImage.getWidth();
        double ratioy = (new Integer(height)).doubleValue() / sourceImage.getHeight();
        AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratiox, ratioy), null);
        BufferedImage bufImg = op.filter(sourceImage, null);
        return bufImg;
    }

}
